package com.wzdigit.wms.wms.service.wms2sap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.common.utils.SapWebServiceUtil;
import com.wzdigit.wms.web.service.common.wms2sap.ZDT_MsgHeader;
import com.wzdigit.wms.web.service.wms2sap.outstore.ZDT_071_Req;
import com.wzdigit.wms.web.service.wms2sap.outstore.ZDT_071_ReqCDK;
import com.wzdigit.wms.web.service.wms2sap.outstore.ZDT_071_RspResult;
import com.wzdigit.wms.web.service.wms2sap.outstore.ZSI_071_WMS2SAP_OutProxy;
import com.wzdigit.wms.wms.service.mid.IfPostbackService;
import com.wzdigit.wms.wms.strategy.webservice.iservice.ISendWebService;
import com.wzdigit.wms.wms.strategy.webservice.type.SendWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Date;
import java.util.List;


/*
     采购订单回写
    * @author shuaic
    * @date 2021/6/17 9:47
*/
@Slf4j
@Service
@SendWebService(value = TopicEnum.TOPIC_SAP_OUT_STORE, name = "SAP_出库单回写")
public class OutStoreService implements ISendWebService {

    @Autowired
    IfPostbackService ifPostbackService;

    @Value("${sap.web.service.protocol-head}")
    private String protocolHead;

    @Value("${sap.web.service.outStore-url}")
    private String uri;

    @Value("${wzdigit.web.service.sap.ip}")
    private String ip;








    /**
     * 定时任务调用SAP的【采购订单接口】
     *
     * @return
     */
    public ZDT_071_RspResult[] report(List<ZDT_071_ReqCDK> records) {
        log.info("开始调【SAP采购订单接口】");
        //发送【向SAP报检】的路径
        String urlString = protocolHead + ip + uri;

        log.info("发送报文的路径:" + urlString);

        ZSI_071_WMS2SAP_OutProxy proxy = new ZSI_071_WMS2SAP_OutProxy  ();

        proxy.setEndpoint(urlString);

        log.info("ZSI_071_WMS2SAP_OutProxy:" + proxy.toString());

        // 消息头
        ZDT_MsgHeader header = SapWebServiceUtil.getHeader();

        log.info("header:" + header);


        //输出请求的核心报文
        try {
            for (ZDT_071_ReqCDK record : records) {

                //格式化生成的XML报文
                JAXBContext jc = JAXBContext.newInstance(ZDT_071_ReqCDK.class);
                Marshaller ms = jc.createMarshaller();
                ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                Writer writer = new StringWriter();
                ms.marshal(record, writer);

                log.info("发送报文的核心内容【xml】:" + writer.toString());
            }
        } catch (JAXBException e) {
            e.printStackTrace();
            log.error("转成XML出错");
        }


        ZDT_071_Req req = new ZDT_071_Req();

        // 消息头
        req.setPI(header);
        // 记录
        ZDT_071_ReqCDK [] reqRECORDS = records.toArray(new ZDT_071_ReqCDK [records.size()]);
        req.setCDK(reqRECORDS);

        ZDT_071_RspResult[] rsp = null;


        try {
            //调接口
            rsp = proxy.ZSI_071_WMS2SAP_Out(req);
        } catch (Exception ex) {
            ex.printStackTrace();
        }



        //输出请求的核心报文
        try {
            for (ZDT_071_RspResult rspRecordHead : rsp) {

                //格式化生成的XML报文
                JAXBContext jc = JAXBContext.newInstance(ZDT_071_RspResult.class);
                Marshaller ms = jc.createMarshaller();
                ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                Writer writer = new StringWriter();
                ms.marshal(rspRecordHead, writer);

                log.info("【SAP_采购订单接口】返回报文的核心内容【xml】:" + writer.toString());
            }
        } catch (JAXBException e) {
            e.printStackTrace();
            log.error("转成XML出错");
        }

        return rsp;
    }


    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Object send(Object object) {

        IfPostback postback = new IfPostback();

        //构造发送的数据
        IfPostback ifPostback = (IfPostback) object;
        String postbackContent = ifPostback.getPostbackContent();
        log.info(postbackContent);


        List<ZDT_071_ReqCDK > reqRECORDS = JSON.parseObject(postbackContent, new TypeReference<List<ZDT_071_ReqCDK >>() {
        });


        //回参的JSON
        String returnJson = new String();
        //系统异常标识
        boolean flag = false;

        ZDT_071_RspResult[] report =null;
        try {
            report = report(reqRECORDS);
            //回写更新
            returnJson = JSON.toJSONString(report);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("调SAP采购订单接口异常，日志打印三次");
            log.error("调SAP采购订单接口异常，日志打印三次");
            log.error("调SAP采购订单接口异常，日志打印三次");
            //发生异常，更新标识
            flag = true;
        } finally {

            if (flag) {
                //调接口异常，解析异常等
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setPostbackResult(BackResultEnum.SYSTEM_ERROR_STATE.getCode());

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            } else {
                //正常返回报文
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setReturnMessage(returnJson);

                postback.setPostbackResult(BackResultEnum.BUSINESS_SUCCESS_STATE.getCode());
                for (ZDT_071_RspResult records : report) {
                    if (records.getRESPONSE().equals("E")) {
                        postback.setPostbackResult(BackResultEnum.BUSINESS_FAIL_STATE.getCode());
                        continue;
                    }
                }

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            }
        }

        return postback;
    }
}
